//s循环移位，环状形式，复制当前字串或数组到最后，然后遍历初始长度

//贡献法，通过计算每一部分的贡献算出整体的贡献

//二维转一维
//f[i][j] 对应下标 n * i + j

//同一条直线上的点的特性：x相等，y相等，x + y相等，x - y相等
//一个点可能分别贡献四种情况，x[a] ++;y[b] ++;sum[a + b] ++;ce[a - b] ++;

// 判断区间是否相交
int x1,y1,x2,y2
max(x1,x2)<=min(y1,y2)//有交集
//求区间交集
min(r,R)−max(l,L)

//二进制枚举子集
for(int i = 2; i <= n; i ++)
{
	for(int j = (i - 1) & i ; j ; j = (j - 1) & i)
	{
		cout << i << ' ' << j << endl;
	}
}

//覆盖网格内直线经过的所有点					
void add(int x1,int y1,int x2,int y2)
{
    int tx=x1-x2,ty=y1-y2,gcd=__gcd(abs(tx),abs(ty));
    tx/=gcd,ty/=gcd;
    int xx=x1,yy=y1;
    while(xx>=1 && xx<=n && yy>=1 && yy<=n) tip[xx][yy]=1,xx+=tx,yy+=ty;
    xx=x1,yy=y1;
    while(xx>=1 && xx<=n && yy>=1 && yy<=n) tip[xx][yy]=1,xx-=tx,yy-=ty;
}    

//__int128输入输出
#define int __int128
__int128 read() {
    __int128 f = 1, w = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch <= '9' && ch >= '0') {
        w = w * 10 + ch - '0';
        ch = getchar();
    }
    return f * w;
}
 
void print(__int128 x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9)
        print(x / 10);
    putchar(x % 10 + '0');
}
 
__int128 qpow(__int128 x, __int128 y) {
    __int128 res = 1;
    while (y) {
        if (y & 1) {
            res = 1ll * x * res % N;
        }
        y >>= 1;
        x = 1ll * x * x % N;
    }
    return res;
}
 __int128 n, m;
n = read(), m = read();
__int128 ans = qpow (2, n);
__int128 sum = qpow(ans, m);
print(sum);

//快速取模
using i128 = __int128_t;
md.init(mod);
struct Mod{
    LL m,p;
    void init(int pp){
        m = ((i128)1 << 64) / pp;
        p = pp;
    }
    LL operator () (LL x) {
        return x - ((i128(x) * m) >> 64) * p;
    }
}md;    

//预处理log2 + 1 的值
for(int i = 1; i <= n; ++i) //预先算出log_2(i)+1的值，用的时候直接调用就可以了
	  lg[i] = lg[i-1] + (1 << lg[i-1] == i);
//head

//防止longlong的sqrt掉精度
LL mysqrt(LL y)
{
    LL l = 0;
    LL r = 1e9;
    while(r - l > 1)
    {
        LL mid = (l + r) / 2;
        if(mid * mid <= y) l = mid;
        else r = mid;
    }
    return l;
}

//(long long)sqrtl(long long x)

//结构体优先队列排序
 
struct Nodep
{
    int r,idx;
};


bool operator <(const Nodep &a,const Nodep &b)
{
    return a.r < b.r;
}
struct P{
    int x;
    int y;
    bool operator<(const P &o) const{
        if(dis(x,y) != dis(o.x,o.y)) return dis(x,y) < dis(o.x,o.y);
        else if(x != o.x) return x < o.x;
        else return y < o.y;
    }
};

// 存储对角线有一个小技巧：
// 从左上到右下的对角线满足 x+y 都相等。
// 从左下到右上的对角线满足 x−y 都相等。


#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<cstdio>
#include<algorithm>
#include<string>
#include<string.h>
#include<queue>
#include<math.h>
#include<set>
#include<functional>
using namespace std;
using ull = unsigned long long;
using i128 = __int128_t;
inline int inc(int x,int v,int mod){x+=v;return x>=mod?x-mod:x;}//代替取模+
#define endl '\n'
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;

const int N = 2e3 + 10, M = 1e5 + 10;

inline int read()
{
    int x = 0,f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
        x = x * 10 + ch - '0',ch = getchar();
    return x * f;
}


void solve()
{
    
}


signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int tt;
    cin >> tt;
    //tt = 1;
    while(tt --)
    {
        solve();
    }   
}
//交互
int chick(int x,int y)
{
    std::cout << "? " << x << " " << y << endl;
    int res;
    std::cin >> res;
    return res;
}
 std::cout << "! " << x << endl;
 

//枚举所有区间的方法

for(int i = 1; i <= n; i ++)
{
    int sum = cnt;
    //区间为奇数
    int l = i;
    int r = i;
    while(l >= 1 && r <= n)
    {
        //
        l --; r ++;
    }
    sum = cnt;
    //区间为偶数
    l = i - 1;
    r = i;
    while(l >= 1 && r <= n)
    {
        //
        l --; r ++;
    }
}
//向上取整可以采用技巧 分子+分母-1 / 分母 来实现
//向下取整可以采用技巧 采用floor 函数，而不是默认的整数除法，因为cpp运算时，整数除法是向0取整的，如果出现负数，则会发生错误